package com.qaml.mes.device.application.task;

import com.alibaba.nacos.common.utils.CollectionUtils;
import com.qaml.mes.device.dao.*;
import com.qaml.mes.device.repository.*;
import com.qaml.mes.device.utils.DateUtils;
import com.qaml.mes.device.utils.IdGenerateUtils;
import com.qaml.mes.device.enums.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.util.*;

/**
 * @ClassName CreateCheckOrderTask
 * @Description 定时任务创建点检任务单
 * @Author leikai
 * @Date 2024/3/5 0005 14:45
 * @Version 1.0
 */
@RefreshScope
@Component
@Slf4j
public class CreateCheckOrderTask {

    @Resource
    private EqpAttachmentRepository eqpAttachmentRepository;

    @Resource
    private CheckUpkeepInfoRepository checkUpkeepInfoRepository;

    @Resource
    private CheckUpkeepItemRepository checkUpkeepItemRepository;

    @Resource
    private CheckUpkeepUserRepository checkUpkeepUserRepository;

    @Resource
    private CheckUpkeepRecordRepository checkUpkeepRecordRepository;

    @Resource
    private CheckUpkeepRecordItemRepository checkUpkeepRecordItemRepository;

    @Resource
    private CheckUpkeepMessageRepository checkUpkeepMessageRepository;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private DayOffRepository dayOffRepository;

    /**
     * 每天0点30分执行
     * TODO
     */
    @Scheduled(cron = "${check.order.task:0 0/2 * * * ?}")
    public void createCheckOrder() {
        log.info("创建点检任务单开始~");
        List<CheckUpkeepInfoDO> checkUpkeepInfoDOList = checkUpkeepInfoRepository.getCheckUpkeepInfoDOByTypeAndCycle(CheckUpkeepTypeEnum.CHECK.getType(), CycleEnum.DAY.getCode());
        if (CollectionUtils.isEmpty(checkUpkeepInfoDOList)) {
            return;
        }
        Map<Long, List<DayOffConfigDO>> objectObjectHashMap = new HashMap<>();
        for (CheckUpkeepInfoDO checkUpkeepInfoDO : checkUpkeepInfoDOList) {
            List<DayOffConfigDO> dayOffConfigDOS = CreateUpkeepOrderTask.checkDayOffData(objectObjectHashMap, checkUpkeepInfoDO, dayOffRepository);
            if (CollectionUtils.isEmpty(dayOffConfigDOS)) {
                try {
                    transactionTemplate.executeWithoutResult(status -> {
                        try {
                            // 保存检保记录
                            String checkUpkeepRecordId = saveCheckUpkeepInfo(checkUpkeepInfoDO);
                            // 保存检保项目条目记录
                            saveRecordItem(checkUpkeepInfoDO, checkUpkeepRecordId);
                            // 发送点检消息
                            saveMessage(checkUpkeepInfoDO, checkUpkeepRecordId);
                        } catch (DuplicateKeyException e) {
                            log.warn("重复创建点检任务单~, 检保项目编号:{}", checkUpkeepInfoDO.getCheckUpkeepId());
                        }

                    });
                } catch (Exception e) {
                    log.error("检保项目生成点检任务单异常 {}", checkUpkeepInfoDO.getCheckUpkeepId(), e);
                }
            } else {
                log.info("当前租户 {} 因当前时间配置了假期管理数据,所以无需生成点检单", checkUpkeepInfoDO.getTenantId());
            }
        }
        log.info("创建点检任务单结束~");

    }

    private void saveMessage(CheckUpkeepInfoDO checkUpkeepInfoDO, String checkUpkeepRecordId) {
        List<CheckUpkeepUserDO> checkUpkeepUserDOS = checkUpkeepUserRepository.getByCheckUpkeepIdAndStatusNoTenantId(checkUpkeepInfoDO.getCheckUpkeepId(),
                CheckUpkeepUserTypeEnum.CHECK.getType());
        if (CollectionUtils.isNotEmpty(checkUpkeepUserDOS)) {
            List<CheckUpkeepMessageDO> checkUpkeepMessages = new ArrayList<>();
            checkUpkeepUserDOS.forEach(checkUpkeepUserDO -> {
                CheckUpkeepMessageDO checkUpkeepMessageDO = new CheckUpkeepMessageDO();
                checkUpkeepMessageDO.setId(IdGenerateUtils.getIdStr());
                checkUpkeepMessageDO.setCheckUpkeepId(checkUpkeepInfoDO.getCheckUpkeepId());
                checkUpkeepMessageDO.setCheckUpkeepRecordId(checkUpkeepRecordId);
                checkUpkeepMessageDO.setType(CheckUpkeepMessageTypeEnum.CHECK.getType());
                checkUpkeepMessageDO.setUserId(checkUpkeepUserDO.getUserId());
                checkUpkeepMessageDO.setUserName(checkUpkeepUserDO.getUserName());
                checkUpkeepMessageDO.setSendTime(new Date());
                checkUpkeepMessageDO.setStatus(CheckUpkeepStatusEnum.NO_COMMIT.getType());
                checkUpkeepMessageDO.setCheckUpkeepDate(DateUtils.getStartDate(new Date()));
                checkUpkeepMessageDO.setEqpName(checkUpkeepInfoDO.getEqpName());
                checkUpkeepMessageDO.setIsRead(0);
                checkUpkeepMessages.add(checkUpkeepMessageDO);
            });
            checkUpkeepMessageRepository.saveBatch(checkUpkeepMessages);
        }
    }

    private void saveRecordItem(CheckUpkeepInfoDO checkUpkeepInfoDO, String checkUpkeepRecordId) {
        List<CheckUpkeepItemDO> checkUpkeepItemDOS = checkUpkeepItemRepository.getByCheckUpkeepId(checkUpkeepInfoDO.getCheckUpkeepId());
        if (CollectionUtils.isNotEmpty(checkUpkeepItemDOS)) {
            List<CheckUpkeepRecordItemDO> checkUpkeepRecordsList = new ArrayList<>();
            checkUpkeepItemDOS.forEach(checkUpkeepItemDO -> {
                CheckUpkeepRecordItemDO checkUpkeepRecordItemDO = new CheckUpkeepRecordItemDO();
                checkUpkeepRecordItemDO.setCheckUpkeepRecordId(checkUpkeepRecordId);
                checkUpkeepRecordItemDO.setCheckItem(checkUpkeepItemDO.getCheckItem());
                checkUpkeepRecordItemDO.setCheckUpkeepItemId(checkUpkeepItemDO.getId());
                checkUpkeepRecordItemDO.setId(IdGenerateUtils.getIdStr());
                checkUpkeepRecordItemDO.setStatus(1);
                checkUpkeepRecordItemDO.setTenantId(checkUpkeepInfoDO.getTenantId());
                checkUpkeepRecordsList.add(checkUpkeepRecordItemDO);
            });
            checkUpkeepRecordItemRepository.saveBatch(checkUpkeepRecordsList);
        }
    }

    private String saveCheckUpkeepInfo(CheckUpkeepInfoDO checkUpkeepInfoDO) {
        CheckUpkeepRecordDO checkUpkeepRecordDO = new CheckUpkeepRecordDO();
        checkUpkeepRecordDO.setCheckUpkeepId(checkUpkeepInfoDO.getCheckUpkeepId());
        checkUpkeepRecordDO.setEqpId(checkUpkeepInfoDO.getEqpId());
        checkUpkeepRecordDO.setEqpCode(checkUpkeepInfoDO.getEqpCode());
        checkUpkeepRecordDO.setEqpName(checkUpkeepInfoDO.getEqpName());
        checkUpkeepRecordDO.setType(checkUpkeepInfoDO.getType());
        checkUpkeepRecordDO.setCycle(checkUpkeepInfoDO.getCycle());
        checkUpkeepRecordDO.setLineBody(checkUpkeepInfoDO.getLineBody());
        checkUpkeepRecordDO.setTenantId(checkUpkeepInfoDO.getTenantId());
        // 检保时间
        Date now = new Date();
        checkUpkeepRecordDO.setCheckUpkeepDate(DateUtils.getStartDate(now));
        checkUpkeepRecordDO.setCheckUpkeepStartTime(DateUtils.getStartDate(now));
        checkUpkeepRecordDO.setCheckUpkeepEndTime(DateUtils.getEndDate(now));
        checkUpkeepRecordDO.setStatus(CheckUpkeepStatusEnum.NO_COMMIT.getType());
        checkUpkeepRecordDO.setErrResult(0);
        List<EqpAttachmentDO> eqpAttachmentDOS = eqpAttachmentRepository.getByEqpIdListAndType(Collections.singletonList(checkUpkeepInfoDO.getEqpId()), AttachmentTypeEnum.IMAGE.getType());
        if (CollectionUtils.isNotEmpty(eqpAttachmentDOS)) {
            EqpAttachmentDO eqpAttachmentDO = eqpAttachmentDOS.get(0);
            checkUpkeepRecordDO.setImageUrl(eqpAttachmentDO.getAttachmentUrl());
        }

        checkUpkeepRecordRepository.saveCheckUpkeepRecordDO(checkUpkeepRecordDO);
        return checkUpkeepRecordDO.getId();
    }
}